package com.csp.mingyue.system.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csp.mingyue.common.core.enums.UserStatus;
import com.csp.mingyue.common.core.exception.UserException;
import com.csp.mingyue.common.mybatis.page.PageCommon;
import com.csp.mingyue.common.satoken.utils.LoginHelper;
import com.csp.mingyue.common.security.support.UserPasswordProperties;
import com.csp.mingyue.system.api.dto.UserAddOrEditDto;
import com.csp.mingyue.system.api.dto.UserQueryDto;
import com.csp.mingyue.system.api.entity.SysUser;
import com.csp.mingyue.system.api.vo.LoginUser;
import com.csp.mingyue.system.api.vo.SysUserVo;
import com.csp.mingyue.system.api.vo.UserInfoVo;
import com.csp.mingyue.system.mapper.SysUserMapper;
import com.csp.mingyue.system.service.SysMenuService;
import com.csp.mingyue.system.service.SysRoleService;
import com.csp.mingyue.system.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * 用户表 服务实现类
 *
 * @author Strive
 * @since 2023-06-06 03:15:20
 */
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

	private final SysUserMapper sysUserMapper;

	private final SysRoleService sysRoleService;

	private final SysMenuService sysMenuService;

	private final UserPasswordProperties userPasswordProperties;

	@Override
	public LoginUser getSysUserInfoByUsername(String username) {
		SysUser sysUser = this.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));

		if (Objects.isNull(sysUser)) {
			throw new UserException("用户不存在");
		}

		if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) {
			throw new UserException("用户已" + UserStatus.DISABLE.getInfo());
		}

		return buildLoginUser(sysUser);
	}

	@Override
	public LoginUser getSysUserInfoByPhone(String phone) {
		SysUser sysUser = this.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhone, phone));

		if (Objects.isNull(sysUser)) {
			throw new UserException("号码不存在");
		}

		if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) {
			throw new UserException("号码已" + UserStatus.DISABLE.getInfo());
		}

		return buildLoginUser(sysUser);
	}

	@Override
	public LoginUser getSysUserInfoByEmail(String email) {
		SysUser sysUser = this.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, email));

		if (Objects.isNull(sysUser)) {
			throw new UserException("邮箱不存在");
		}

		if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) {
			throw new UserException("邮箱已" + UserStatus.DISABLE.getInfo());
		}

		return buildLoginUser(sysUser);
	}

	/**
	 * 构建登录用户
	 */
	private LoginUser buildLoginUser(SysUser user) {
		LoginUser loginUser = BeanUtil.copyProperties(user, LoginUser.class);

		loginUser.setMenuPermission(sysMenuService.getMenuPermission(user.getUserId()));
		loginUser.setRolePermission(sysRoleService.getRolePermission(user.getUserId()));
		return loginUser;
	}

	@Override
	public IPage<SysUserVo> getSysUsers(PageCommon page, UserQueryDto dto) {
		return sysUserMapper.getUserVosPage(page.build(), dto);
	}

	@Override
	public UserInfoVo getUserInfo() {
		UserInfoVo result = new UserInfoVo();

		LoginUser loginUser = LoginHelper.getLoginUser();
		SysUser sysUser = this.getSysUserInfoByUserId(loginUser.getUserId());
		result.setSysUserVo(BeanUtil.copyProperties(sysUser, SysUserVo.class));

		// 设置角色列表
		result.setRolePermission(loginUser.getRolePermission());

		// 设置权限列表
		result.setMenuPermission(loginUser.getMenuPermission());

		return result;
	}

	private SysUser getSysUserInfoByUserId(Long userId) {
		return this.getById(userId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean addOrEdit(UserAddOrEditDto dto) {
		SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);

		// 添加用户
		if (Objects.isNull(sysUser.getUserId())) {
			// 密码加密
			sysUser.setPassword(BCrypt.hashpw(sysUser.getPassword(), userPasswordProperties.getSalt()));
		}

		boolean flag = this.saveOrUpdate(sysUser);
		if (!flag) {
			throw new UserException("用户信息保存异常");
		}

		// 保存角色关系
		flag = sysRoleService.addUserRole(sysUser.getUserId(), dto.getRoleCode());
		if (!flag) {
			throw new UserException("用户角色信息保存异常");
		}

		return true;
	}

	@Override
	public boolean delUser(Long userId) {
		return sysUserMapper.deleteByIdLogic(userId) > 0;
	}

	@Override
	public boolean register(SysUser sysUser) {
		SysUser oldUser = this
				.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysUser.getUsername()));
		if (Objects.nonNull(oldUser)) {
			throw new UserException("用户已注册");
		}

		sysUser.setNickname(sysUser.getUsername());
		sysUser.setPassword(BCrypt.hashpw(sysUser.getPassword(), userPasswordProperties.getSalt()));
		return this.save(sysUser);
	}

}
